package com.lmm.rpc.server.processor;

import com.lmm.rpc.core.cache.LocalServerCache;
import com.lmm.rpc.core.cluster.RemoteServerInfo;
import com.lmm.rpc.core.exception.RpcException;
import com.lmm.rpc.core.register.Registry;
import com.lmm.rpc.core.server.Server;
import com.lmm.rpc.core.util.IPUtil;
import com.lmm.rpc.server.annotation.RpcPrivider;
import com.lmm.rpc.server.autoconfig.RpcServerProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.CommandLineRunner;

/**
 * @title: RpcServerProcessor
 * @Description: 服务提供者扩展
 * @Author Lmm
 * @Date: 2022/10/9 11:18
 * @Version 1.0
 */
@Slf4j
public class RpcServerProcessor implements BeanPostProcessor, CommandLineRunner {

    /**
     * 注册中心
     * */
    private Registry registry;
    /**
     * 服务配置
     * */
    private RpcServerProperties properties;
    /**
     * 通讯服务器
     * */
    private Server nettyServer;

    public RpcServerProcessor(Registry registry,RpcServerProperties properties,Server nettyServer){
        this.registry = registry;
        this.properties = properties;
        this.nettyServer = nettyServer;
    }

    @Override
    public void run(String... args) throws Exception {

        try {
            new Thread(()->{
                nettyServer.start(properties.getPort());
            },"nettyServer").start();

        }catch (Exception e){
            log.error("server start fail,reason:"+e.getMessage());
            throw new RpcException("server start fail",e);
        }
        log.info("rpc server start success,port:【{}】,env:【{}】",properties.getPort(),properties.getEnv());
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try {
                // 关闭之后把服务从ZK上清除
                registry.destroy();
                nettyServer.stop();
//                LocalServerCache.clear();
            }catch (Exception ex){
                log.error("", ex);
            }
        }));
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        RpcPrivider rpcPrivider = bean.getClass().getAnnotation(RpcPrivider.class);
        if (rpcPrivider != null){
            String name = rpcPrivider.interfaceType().getName();
            RemoteServerInfo remoteServerInfo = new RemoteServerInfo();
            remoteServerInfo.setServiceName(name);
            LocalServerCache.store(name,bean);
            remoteServerInfo.setIp(IPUtil.getIpV4());
            remoteServerInfo.setEnable(true);
            remoteServerInfo.setWeight(properties.getWeight());
            remoteServerInfo.setServer(IPUtil.getIpV4());
            remoteServerInfo.setPort(String.valueOf(properties.getPort()));
            registry.registry(remoteServerInfo);
        }
        return bean;
    }
}
